#ifndef _MUNIX_ATBIOS_H
#define	_MUNIX_ATBIOS_H
/*******************************************************************************
 ** Name: atbios.h                                                            **
 ** Description:              **
 **                                                                           **
 ** Open Source Initiative (OSI) Approved License                             **
 **                                                                           **
 ** The contents of this file are subject to the terms of the                 **
 ** Common Development and Distribution License, Version 1.0 only             **
 ** (the "License").  You may not use this file except in compliance          **
 ** with the License.                                                         **
 **                                                                           **
 ** You can find a copy of the license in the license.txt within              **
 ** this distribution or at http://www.munixos.net/licensing.                 **
 ** Software distributed under the License is distributed on an "AS IS"       **
 ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.           **
 ** See the License for the specific language governing permissions           **
 ** and limitations under the License.                                        **
 **                                                                           **
 ** When distributing Covered Code, include this CDDL header in each          **
 ** file and include the License file at $HOME/license.txt.                   **
 ** If applicable, add the following below this header, with the indicated    **
 ** fields enclosed by brackets "[]" replaced with your own identifying       **
 ** information: Portions Copyright [yyyy] [name of copyright owner]          **
 **                                                                           **
 **                                                                           **
 ** Copyright (c) 2009-2010  Barry Gian James.                                **
 ** All rights reserved.                                                      **
 **                                                                           **
 ** Ref: $HeadURL$
 ******************************************************************************/
// Portions (C) 2011 OpenHouseware, LLC.
// All Rights Reserved

// $Id$
// Last Modified $DateTime$ by $Author$
#define _MUNIX_ATBIOS_ID_ "$Id$"
// Last Modified $DateTime: 2010/02/12 01:42:30 $ by $Author$

#include "common.h"
#include "mtime.h"
#include "io.h"
#include "usart.h"
#include "spi.h"
#include "twi.h"

// The pin/port assignments are well-known for the ATBIOS so they
// are defined here.
#define PIN_VOLTAGE_LEFT    PA7 // ADC reads voltage before resistor
#define PIN_VOLTAGE_RIGHT   PA6 // ADC reads voltage after resistor
#define PIN_VIDEO_CTRL      PA5 // control line to VGA subsystem
#define PIN_THUMB_AXIS1     PA4 // thumbstick controller on LCD console
#define PIN_THUMB_AXIS2     PA3 // ditto
#define PIN_THUMB_SEL       PA2 // you can push it and it acts as a button
#define PIN_PIC_CLOCK       PA1 // interrupt ctrlr request for system time
#define PIN_AMPS_RESET      PA0 // BIOS holds CPU's in RESET
#define PIN_SPI_SCK         PB7 // SPI and ISP
#define PIN_SPI_MISO        PB6
#define PIN_SPI_MOSI        PB5
#define PIN_BUSX_CS         PB4 // SPI bus expander chip select
#define PIN_BUSX_INT        PB3 // SPI bus expander interrupt line
#define PIN_RTC_INT         PB2 // RTC interrupt line
#define PIN_RTC_SCL         PB1 // RTC I2C clock
#define PIN_RTC_SDA         PB0 // RTC I2C data
#define PIN_BUS_AD7        PC7  // Pins 7 through 0 of the Address/Data bus
#define PIN_BUS_AD6        PC6
#define PIN_BUS_AD5        PC5
#define PIN_BUS_AD4        PC4
#define PIN_BUS_AD3        PC3
#define PIN_BUS_AD2        PC2
#define PIN_BUS_AD1        PC1
#define PIN_BUS_AD0        PC0
#define PIN_CTRLBUS4        PD7 // Pins 4 through 0 of the control bus
#define PIN_CTRLBUS3        PD6
#define PIN_CTRLBUS2        PD5
#define PIN_CTRLBUS1        PD4
#define PIN_CTRLBUS0        PD3
#define PIN_PIC_TEMP        PD2 // interrupt ctrlr request for system temp
#define PIN_CONSOLE_TX      PD1 // USART0 Debug Console Serial Port
#define PIN_CONSOLE_RX      PD0 // USART0 Debug Console Serial Port

// Because the ATBIOS proxies so many devices, it has to use a I/O port expander
// So several key signals are themselves proxied through the expander to the bios
// These are those aliases referencing pins on the expander.
#define PIN_LCD_ENA         0
#define PIN_LCD_CLK         1
#define PIN_LCD_RW          2
#define PIN_LCD_DATA        3
#define PIN_RESET_BTN       4
#define PIN_SPI_TEMP_CS     6
#define PIN_SPI_MEM_CS      7

#define ATBIOS_EXT_CLOCK    1   // ATBIOS uses an external clock signal
#define LOW_VOLTAGE_ALARM   3   // 3V and we alarm
#define HIGH_TEMP_ALARM     100 // 100C

////////////////////////////////[ Temp sensor
#define TEMP_RD_ADDR        0x00
#define TEMP_WR_ADDR        0x80
#define TEMP_MSB_ADDR       0x02
#define TEMP_LSB_ADDR       0x01
#define TEMP_CTRL_ADDR      0x00
#define TEMP_MFGID_ADDR     0x03
#define TEMP_MODE_ONESHOT   0x08


////////////////////////////////[ RTC
// Default RTC:
#define RTC_RD_ADDR         0xA3
#define RTC_WR_ADDR         0xA2

enum class RTCAddr : uint8
{
    CtrlStatus1, CtrlStatus2,
    Sec, Minute, Hour, Day, Weekday,
    Month, Year
};

enum class RTCAlarm : uint8
{
    Minute=0x09, Hour=0x0A, Day=0x0B, Weekday=0x0C
};
#define RTC_CLKOUT_CTRL     0x0D
enum class RTCTimer : uint8
{
    TimerCtrl=0x0E, Countdown=0x0F
};

////////////////////////////////[ Flash memory
// Default ATBIOS flash: W25X80
enum class BIOSFlashAddr : uint8
{
    WREN=0x06, WRDA=0x04, RDSR=0x05, WRSR=0x01, RD=0x03,
    FRD=0x0B, FRDD=0x3B, PPGM=0x02, SERA=0x20, BERA=0xD8,
    CERA=0xC7, PWDN=0xB9, DEVID1=0xAB, DEVID2=0x90, JEDEC=0x9F
};
#define MEM_BIOS_BUSY       0x01
#define BIOS_SECTOR_SZ      4096
#define BIOS_BLOCK_SZ       65536
#define BIOS_PAGE_SZ        256
#define BIOS_PAGE_NUM       4096
#define BIOS_SECTOR_NUM     256
#define BIOS_BLOCK_NUM      16

struct BIOSFlashParams
{
    uint8   mfg;
    uint8   memType;
    uint8   capacity;
};
//  Memory Protection Mask             Write Protects
#define BIOS_MEM_PROTECT0   0x00    // NONE
#define BIOS_MEM_PROTECT1   0x04    // 0x0F0000 - 0x0FFFFF, block 15
#define BIOS_MEM_PROTECT2   0x08    // 0x0E0000 - 0x0FFFFF, blocks 14,15
#define BIOS_MEM_PROTECT3   0x0C    // 0x0C0000 - 0x0FFFFF, blocks 12-15
#define BIOS_MEM_PROTECT4   0x10    // 0x080000 - 0x0FFFFF, blocks 8-15
#define BIOS_MEM_PROTECT5   0x24    // 0x000000 - 0x00FFFF, block 0
#define BIOS_MEM_PROTECT6   0x28    // 0x000000 - 0x01FFFF, blocks 0,1
#define BIOS_MEM_PROTECT7   0x2C    // 0x000000 - 0x03FFFF, blocks 0-3
#define BIOS_MEM_PROTECT8   0x30    // 0x000000 - 0x07FFFF, blocks 0-7
#define BIOS_MEM_PROTECT9   0x14    // 0x000000 - 0x0FFFFF, all 0-15
#define BIOS_MEM_PROTECT10  0x18    // 0x000000 - 0x0FFFFF, all 0-15


////////////////////////////////[ SPI Bus Expander
enum class BusXAddr : uint8
{
    IODIR, IPOL, GPINTEN, DEFVAL, INTCON, IOCON, GPPU,
    INTF, INTLAP, GPIO, OLAT=0x0A
};
// Two pins on the bus expander comprise part of the address and must be
// pulled high or low.  I have pulled them high so set them to 1 here.
#define BUSX_ADDR_A0        1
#define BUSX_ADDR_A1        1
#define BUSX_SPI_TEMPLATE   0b01000110  // part of the SPI address
#define BUSX_SPI_RD         0x01    // these make up the LSB bit
#define BUSX_SPI_WR         0x00    // of the SPI address
#define BUSX_SPI_ADDR(rw)   (BUSX_SPI_TEMPLATE | rw)


#define BIOS_DEBUG_BAUD     57600
////////////////////////////////[ ATBIOS
class ATBIOS
{
public:
    ATBIOS(uint8 a = (uint8)ioaddr::bios);

    bool    Init();
    bool    InitIO();
    bool    InitMem();
    bool    InitKernel();

    uint16  GetVoltage();
    uint8   GetCurrent();
    uint8   GetTemp();

    // Real Time Clock
    void    SetTime(const TimeStruct & ts);
    void    SetDate(const DateStruct & ds);
    TimeStruct GetTime();
    DateStruct GetDate();

    bool    IsInteractive() const { return bInteractive; }
    void    SetInteractive(bool b);

    void    Debug(const char *,bool=false);

    USART & dbg() const { return *debug; }
    SPI &   temp() const { return *spiTemp; }
    SPI &   cfg() const { return *spiConfigFlash; }
    TWI &   rtc() const { return *twiRTC; }

private:
    void    ResetAMPS();
    void    BootAMPS();

    void    SendToVGA(char c);

    uint16  ReadVoltageLeft();
    uint16  ReadVoltageRight();

    bool    bDebug;         // to debug or not to debug
    bool    bInteractive;   // interactive debug or no?
    uint8   addr;                   // bios IO addr

    // Connected to DataFlash config memory via SPI
    // as well as to the temp sensor via SPI
    SPI *   spiConfigFlash;
    SPI *   spiTemp;
    // connected to the RTC via I2C
    TWI *   twiRTC;
    USART * debug;
};


////////////[ ATBIOS Menus
#define BIOS_MENU_MAIN      0
#define BIOS_MENU_STD       1
#define BIOS_MENU_ADV       2
#define BIOS_MENU_MCU       3
#define BIOS_MENU_BUS       4
#define BIOS_MENU_EXT       5
#define BIOS_MENU_PWR       6

////////////[ ATBIOS POST Codes










#endif	/* _MUNIX_ATBIOS_H */

